home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Xconq 7.0d37 / source / kernel / side.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-02  |  43.9 KB  |  1,828 lines  |  [TEXT/KAHL]

  1. /* Sides in Xconq.
  2.    Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995
  3.    Stanley T. Shebs.
  4.  
  5. Xconq is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.  See the file COPYING.  */
  9.  
  10. /* This file implements sides and functionality relating to sides in
  11.    general. */
  12.  
  13. /* (should sides and players be listed in arrays a la assignments array? */
  14.  
  15. #include "conq.h"
  16. extern int side_acp_human PROTO ((Side *side));
  17.  
  18. static void init_visible_elevation PROTO ((int x, int y));
  19.  
  20. static void calc_visible_elevation PROTO ((int x, int y));
  21.  
  22. /* Head of the list of all sides. */
  23.  
  24. Side *sidelist;
  25.  
  26. /* Pointer to the side representing independence. */
  27.  
  28. Side *indepside;
  29.  
  30. /* Pointer to the last side of the list. */
  31.  
  32. Side *lastside;
  33.  
  34. /* Temporary used in many places. */
  35.          
  36. Side *tmpside;
  37.  
  38. /* The actual number of sides in a game.  This number never decreases;
  39.    sides no longer playing need to be around for recordskeeping purposes. */
  40.  
  41. int numsides;
  42.  
  43. /* Used to generate the id number of the side. */
  44.  
  45. int nextsideid;
  46.  
  47. /* Pointer to buffer used for readable side description (for debugging). */
  48.  
  49. char *sidedesigbuf = NULL;
  50.  
  51. /* Pointer to the head of the list of players. */
  52.  
  53. Player *playerlist;
  54.  
  55. /* Pointer to the last player of the list, used to add players at end. */
  56.  
  57. Player *last_player;
  58.  
  59. /* The total number of players. */
  60.  
  61. int numplayers;
  62.  
  63. /* Use to generate the id number of each player. */
  64.  
  65. int nextplayerid;
  66.  
  67. char *playerdesigbuf = NULL;
  68.  
  69. /* Init side machinery.   We always have an "independent" side hanging around;
  70.    it will be at the head of the list of sides, but normal side iteration
  71.    finesses this by starting from the second list element.  The independent
  72.    side is also a good placeholder for random stuff. */
  73.  
  74. void
  75. init_sides()
  76. {
  77.     /* Set up the list of sides. */
  78.     sidelist = lastside = (Side *) xmalloc(sizeof(Side));
  79.     /* The independent units' side will be the first one, is always created. */
  80.     indepside = sidelist;
  81.     /* Fill in some properties of the independents' side. */
  82.     indepside->name = "- indep -";
  83.     indepside->noun = "- indep -";
  84.     indepside->adjective = "independent";
  85.     indepside->colorscheme = NULL;
  86.     /* By default, independent units are not identified by an emblem. */
  87.     /* A game design can set this appropriately if desired, however. */
  88.     indepside->emblemname = "none";
  89.     indepside->id = 0;
  90.     /* The independent side is not counted in numsides. */
  91.     numsides = 0;
  92.     /* Regular side ids start at 1 and go up. */
  93.     nextsideid = 1;
  94.     /* Set up the list of players. */
  95.     playerlist = last_player = NULL;
  96.     numplayers = 0;
  97.     nextplayerid = 1;
  98.     /* Set up the player/side assignment array. */
  99.     assignments = (Assign *) xmalloc(MAXSIDES * sizeof(Assign));
  100. }
  101.  
  102. /* Create an object representing a side. */
  103.  
  104. Side *
  105. create_side()
  106. {
  107.     int u;
  108.     Side *newside;
  109.  
  110.     if (numsides >= g_sides_max()) {
  111.     run_error("Cannot have more than %d sides total!", g_sides_max());
  112.     }
  113.     /* Allocate the side object proper. */
  114.     newside = (Side *) xmalloc(sizeof(Side));
  115.     /* Fill in various side slots.  Only those with non-zero/non-NULL
  116.        defaults need have anything done to them. */
  117.     newside->id = nextsideid++;
  118.     /* Always start sides IN the game. */
  119.     newside->ingame = TRUE;
  120.     /* Set up the relationships with other sides. */
  121.     newside->trusts = (short *) xmalloc((g_sides_max() + 1) * sizeof(short));
  122.     newside->trades = (short *) xmalloc((g_sides_max() + 1) * sizeof(short));
  123.     /* Set up per-unit-type slots. */
  124.     newside->counts = (short *) xmalloc(numutypes * sizeof(short));
  125.     newside->tech = (short *) xmalloc(numutypes * sizeof(short));
  126.     newside->inittech = (short *) xmalloc(numutypes * sizeof(short));
  127.     newside->numunits = (short *) xmalloc(numutypes * sizeof(short));
  128.     newside->numlive = (short *) xmalloc(numutypes * sizeof(short));
  129.     for_all_unit_types(u) {
  130.     /* Start unit numbering at 1, not 0. */
  131.     newside->counts[u] = 1;
  132.     }
  133.     newside->itertime = 100;
  134.     newside->unitseveraskside = TRUE;
  135.     newside->autofinish = TRUE;
  136.     /* Set up the default doctrine substructure. */
  137.     init_doctrine(newside);
  138.     newside->startx = newside->starty = -1;
  139.     newside->gaincounts = (short *) xmalloc(numutypes * 3 * sizeof(short));
  140.     newside->losscounts = (short *) xmalloc(numutypes * 3 * sizeof(short));
  141.     newside->atkstats = (long **) xmalloc(numutypes * sizeof(long *));
  142.     newside->hitstats = (long **) xmalloc(numutypes * sizeof(long *));
  143.     /* Link in at the end of the list of sides. */
  144.     newside->next = NULL;
  145.     lastside->next = newside;
  146.     lastside = newside;
  147.     init_side_unithead(newside);
  148.     ++numsides;
  149.     return newside;
  150. }
  151.  
  152. /* To make the double links work, we have to have one pseudo-unit to serve
  153.    as a head.  This unit should not be seen by any outside code. */
  154.  
  155. void
  156. init_side_unithead(side)
  157. Side *side;
  158. {
  159.     if (side->unithead == NULL) {
  160.     side->unithead = (Unit *) create_bare_unit(0);
  161.     side->unithead->next = side->unithead;
  162.     side->unithead->prev = side->unithead;
  163.     }
  164. }
  165.  
  166. /* Quick check to see if we have units. */
  167.  
  168. /* This should be improved to not be fooled by dead units? */
  169.  
  170. int
  171. side_has_units(side)
  172. Side *side;
  173. {
  174.     return (side->unithead != NULL
  175.         && (side->unithead->next != side->unithead));
  176. }
  177.  
  178. /* Set up doctrine structures. */
  179.  
  180. void
  181. init_doctrine(side)
  182. Side *side;
  183. {
  184.     int u;
  185.  
  186.     side->doctrine = (Doctrine *) xmalloc(sizeof(Doctrine));
  187.     /* Allocate just enough unit doctrines for all the defined types. */
  188.     side->udoctrine = (Doctrine *) xmalloc(numutypes * sizeof(Doctrine));
  189.     /* Fill each of those in with good defaults. */
  190.     side->doctrine->everaskside = TRUE;
  191.     for_all_unit_types(u) {
  192.     u_doctrine(side, u, everaskside) = TRUE;
  193.     }
  194. }
  195.  
  196. /* Initialize basic viewing structures for a side.  This happens when the
  197.    side is created (during/after reading but before synthesis). */
  198.  
  199. int
  200. init_view(side)
  201. Side *side;
  202. {
  203.     int terrainset = FALSE;
  204.  
  205.     /* Allocate space for views. */
  206.     /* (should check world validity/compatibility first?) */
  207.     if (side->terrview == NULL) {
  208.     side->terrview = malloc_area_layer(short);
  209.     } else {
  210.     terrainset = TRUE;
  211.     }
  212.     if (side->unitview == NULL) {
  213.     side->unitview = malloc_area_layer(short);
  214.     side->unitviewdate = malloc_area_layer(short);
  215. #if (MAXVIEWHISTORY > 0)
  216.     side->viewhistory[MAXVIEWHISTORY] = malloc_area_layer(long);
  217. #endif
  218.     }
  219.     /* Allocate the vision coverage cache if needed. */
  220.     if (side->coverage == NULL) {
  221.     side->coverage = malloc_area_layer(short);
  222.     }
  223.     return terrainset;
  224. }
  225.  
  226. /* Calculate the centroid of all the starting units. */
  227.  
  228. void
  229. calc_start_xy(side)
  230. Side *side;
  231. {
  232.     int num = 0, sumx = 0, sumy = 0;
  233.     Unit *unit;
  234.  
  235.     for_all_side_units(side, unit) {
  236.     if (in_play(unit)) {
  237.         sumx += unit->x;  sumy += unit->y;
  238.         ++num;
  239.     }
  240.     }
  241.     if (num > 0) {
  242.     side->startx = wrapx(sumx / num);  side->starty = sumy / num;
  243.     }
  244. }
  245.  
  246. /* Get a char string naming the side.  Doesn't have to be pretty. */
  247.  
  248. /* (should synth complete name/adjective from other parts of speech) */
  249.  
  250. char *
  251. side_name(side)
  252. Side *side;
  253. {
  254.     return (side == NULL ? "independent" :
  255.       (side->name ? side->name :
  256.         (side->adjective ? side->adjective : 
  257.          (side->pluralnoun ? side->pluralnoun :
  258.           (side->noun ? side->noun :
  259.            "")))));
  260. }
  261.  
  262. char *
  263. side_adjective(side)
  264. Side *side;
  265. {
  266.     return (side == NULL ? "independent" :
  267.        (side->adjective ? side->adjective :
  268.         (side->pluralnoun ? side->pluralnoun :
  269.          (side->noun ? side->noun :
  270.           (side->name ? side->name :
  271.            "")))));
  272. }
  273.  
  274. /* Given a side, get its "number", which is same as its "id". */
  275.  
  276. int
  277. side_number(side)
  278. Side *side;
  279. {
  280.     return (side == NULL ? indepside->id : side->id);
  281. }
  282.  
  283. /* The inverse function - given a number, figure out which side it is.
  284.    Returns NULL for independent side number and for any failures. */
  285.  
  286. Side *
  287. side_n(n)
  288. int n;
  289. {
  290.     Side *rslt;
  291.  
  292.     if (n < 1) return NULL;
  293.     for_all_sides(rslt) if (rslt->id == n) return rslt;
  294.     return NULL;
  295. }
  296.  
  297. /* This is true when one side controls another. */
  298.  
  299. int
  300. side_controls_side(side, side2)
  301. Side *side, *side2;
  302. {
  303.     if (side == NULL || side2 == NULL) return FALSE;
  304.     return (side == side2 || side2->controlledby == side);
  305. }
  306.  
  307. short *max_control_ranges;
  308.  
  309. static int controller_here PROTO ((int x, int y));
  310.  
  311. static int
  312. controller_here(x, y)
  313. int x, y;
  314. {
  315.     Unit *unit2;
  316.  
  317.     if (distance(x, y, tmpunit->x, tmpunit->y) < 2)
  318.       return FALSE;
  319.     for_all_stack(x, y, unit2) {
  320.     if (side_controls_unit(tmpside, unit2)
  321.         && probability(uu_control(unit2->type, tmpunit->type)))
  322.       return TRUE;
  323.     }
  324.     return FALSE;
  325. }
  326.  
  327. /* This is true if the given side may operate on the given unit. */
  328.  
  329. int
  330. side_controls_unit(side, unit)
  331. Side *side;
  332. Unit *unit;
  333. {
  334.     int dir, x1, y1;
  335.     Unit *unit2;
  336.  
  337.     if (side == NULL || unit == NULL)
  338.       return FALSE;
  339. #ifdef DESIGNERS
  340.     if (side->designer)
  341.       return TRUE;
  342. #endif
  343.     if (side_controls_side(side, unit->side)) {
  344.     /* should check if type is controllable and within control coverage */
  345.     /* should check if unit's cmdr is controlled */
  346.     /* The *unit* side must have the tech to use the unit, the controlling
  347.        side would have to actually take over the unit if it wants to use
  348.        its tech level to control the unit. */
  349.     if (unit->side != NULL && unit->side->tech[unit->type] < u_tech_to_use(unit->type))
  350.       return FALSE;
  351.     if (u_direct_control(unit->type) || unit == side->selfunit)
  352.       return TRUE;
  353.     /* Unit is not under direct control of the side; look for a controlled unit
  354.        that can control this unit. */
  355.     if (max_control_ranges == NULL) {
  356.         int u1, u2;
  357.  
  358.         max_control_ranges = (short *) xmalloc(numutypes * sizeof(short));
  359.         for_all_unit_types(u2) {
  360.         max_control_ranges[u2] = -1;
  361.         for_all_unit_types(u1) {
  362.             max_control_ranges[u2] =
  363.               max(max_control_ranges[u2], uu_control_range(u1, u2));
  364.         }
  365.         }
  366.     }
  367.     if (max_control_ranges[unit->type] >= 0) {
  368.         for_all_stack(unit->x, unit->y, unit2) {
  369.         if (unit != unit2
  370.             && side_controls_unit(side, unit2)
  371.             && probability(uu_control_at(unit2->type, unit->type)))
  372.           return TRUE;
  373.         }
  374.         /* (what about occupants that could be controllers?) */
  375.     }
  376.     if (max_control_ranges[unit->type] >= 1) {
  377.         for_all_directions(dir) {
  378.         if (interior_point_in_dir(unit->x, unit->y, dir, &x1, &y1)) {
  379.             for_all_stack(x1, y1, unit2) {
  380.             if (side_controls_unit(side, unit2)
  381.                 && probability(uu_control_adj(unit2->type, unit->type)))
  382.               return TRUE;
  383.             }
  384.         }
  385.         }
  386.     }
  387.     if (max_control_ranges[unit->type] >= 2) {
  388.         tmpside = side;
  389.         tmpunit = unit;
  390.         return search_around(unit->x, unit->y, max_control_ranges[unit->type],
  391.                      controller_here, &x1, &y1, 1);
  392.     }
  393.     }
  394.     /* (should add something for control for non-owned units?) */
  395.     return FALSE;
  396. }
  397.  
  398. /* This is true if the given side may examine the given unit. */
  399.  
  400. int
  401. side_sees_unit(side, unit)
  402. Side *side;
  403. Unit *unit;
  404. {
  405.     if (side == NULL || unit == NULL)
  406.       return FALSE;
  407.     if (side->designer)
  408.       return TRUE;
  409.     if (side_controls_side(side, unit->side))
  410.       return TRUE;
  411.     return FALSE;
  412. }
  413.  
  414. int
  415. side_sees_image(side, unit)
  416. Side *side;
  417. Unit *unit;
  418. {
  419.     if (side == NULL || unit == NULL)
  420.       return FALSE;
  421.     if (side->designer)
  422.       return TRUE;
  423.     if (g_see_all())
  424.       return TRUE;
  425.     if (side_controls_side(side, unit->side))
  426.       return TRUE;
  427.     if (in_area(unit->x, unit->y)
  428.     && side->coverage != NULL
  429.     && cover(side, unit->x, unit->y) > 0)
  430.       return TRUE;
  431.     return FALSE;
  432. }
  433.  
  434. int
  435. num_units_in_play(side, u)
  436. Side *side;
  437. int u;
  438. {
  439.     int num = 0;
  440.     Unit *unit;
  441.  
  442.     if (side != NULL && side->ingame) {
  443.       for_all_side_units(side, unit) {
  444.     if (unit->type == u
  445.         && in_play(unit)
  446.         && completed(unit))
  447.       ++num;
  448.       }
  449.     }
  450.     return num;
  451. }
  452.  
  453. int
  454. num_units_incomplete(side, u)
  455. Side *side;
  456. int u;
  457. {
  458.     int num = 0;
  459.     Unit *unit;
  460.  
  461.     if (side != NULL && side->ingame) {
  462.       for_all_side_units(side, unit) {
  463.     if (unit->type == u && alive(unit) && !completed(unit)) ++num;
  464.       }
  465.     }
  466.     return num;
  467. }
  468.  
  469. Unit *
  470. find_next_unit(side, prevunit)
  471. Side *side;
  472. Unit *prevunit;
  473. {
  474.     Unit *unit = NULL;
  475.  
  476.     if (side != NULL) {
  477.     if (prevunit == NULL) prevunit = side->unithead;
  478. #ifdef USE_CONSOLE
  479.     printf("Find_next_unit starting with %s\n", unit_desig(prevunit));
  480. #endif
  481.     for (unit = prevunit->next; unit != prevunit; unit = unit->next) {
  482. #ifdef USE_CONSOLE
  483.         printf("Looking at %s", unit_desig(unit));
  484.         printf(", prev is %s", unit_desig(unit->prev));
  485.         printf(", next is %s", unit_desig(unit->next));
  486.         printf("\n");
  487. #endif
  488.         if (is_unit(unit) && unit->id > 0
  489.         && alive(unit)
  490.         && inside_area(unit->x, unit->y)) {
  491.         return unit;
  492.         }
  493.     } 
  494.     }
  495.     return NULL;
  496. }
  497.  
  498. Unit *
  499. find_prev_unit(side, nextunit)
  500. Side *side;
  501. Unit *nextunit;
  502. {
  503.     Unit *unit = NULL;
  504.     
  505.     if (side != NULL) {
  506.     if (nextunit == NULL) nextunit = side->unithead;
  507.     for (unit = nextunit->prev; unit != nextunit; unit = unit->prev) {
  508.         if (is_unit(unit) && unit->id > 0
  509.         && alive(unit)
  510.         && inside_area(unit->x, unit->y)) {
  511.         return unit;
  512.         }
  513.     } 
  514.     }
  515.     return NULL;
  516. }
  517.  
  518. Unit *
  519. find_next_actor(side, prevunit)
  520. Side *side;
  521. Unit *prevunit;
  522. {
  523.     Unit *unit = NULL;
  524.     
  525.     if (side != NULL) {
  526.     if (prevunit == NULL) prevunit = side->unithead;
  527.     for (unit = prevunit->next; unit != prevunit; unit = unit->next) {
  528.         if (is_unit(unit) && unit->id > 0
  529.         && alive(unit)
  530.         && inside_area(unit->x, unit->y)
  531.         && (unit->act && unit->act->initacp)) {
  532.         return unit;
  533.         }
  534.     } 
  535.     }
  536.     return NULL;
  537. }
  538.  
  539. Unit *
  540. find_prev_actor(side, nextunit)
  541. Side *side;
  542. Unit *nextunit;
  543. {
  544.     Unit *unit = NULL;
  545.  
  546.     if (side != NULL) {
  547.     if (nextunit == NULL) nextunit = side->unithead;
  548.     for (unit = nextunit->prev; unit != nextunit; unit = unit->prev) {
  549.         if (is_unit(unit) && unit->id > 0
  550.         && alive(unit)
  551.         && inside_area(unit->x, unit->y)
  552.         && (unit->act && unit->act->initacp)) {
  553.         return unit;
  554.         }
  555.     } 
  556.     }
  557.     return NULL;
  558. }
  559.  
  560. /* (should move these to kernel) */
  561.  
  562. Unit *
  563. find_next_mover(side, prevunit)
  564. Side *side;
  565. Unit *prevunit;
  566. {
  567.     Unit *unit = NULL;
  568.  
  569.     if (side != NULL) {
  570.         if (prevunit == NULL) prevunit = side->unithead;
  571.         for (unit = prevunit->next; unit != prevunit; unit = unit->next) {
  572.             if (is_unit(unit) && unit->id > 0
  573.                 && alive(unit)
  574.                 && inside_area(unit->x, unit->y)
  575.                 && (unit->act && unit->act->acp > 0)) {
  576.                 return unit;
  577.             }
  578.         } 
  579.     }
  580.     return NULL;
  581. }
  582.  
  583. Unit *
  584. find_prev_mover(side, nextunit)
  585. Side *side;
  586. Unit *nextunit;
  587. {
  588.     Unit *unit = NULL;
  589.  
  590.     if (side != NULL) {
  591.     if (nextunit == NULL) nextunit = side->unithead;
  592.     for (unit = nextunit->prev; unit != nextunit; unit = unit->prev) {
  593.         if (is_unit(unit) && unit->id > 0
  594.         && alive(unit)
  595.         && inside_area(unit->x, unit->y)
  596.         && (unit->act && unit->act->acp > 0)) {
  597.         return unit;
  598.         }
  599.     } 
  600.     }
  601.     return NULL;
  602. }
  603.  
  604. Unit *
  605. find_next_awake_mover(side, prevunit)
  606. Side *side;
  607. Unit *prevunit;
  608. {
  609.     Unit *unit = NULL;
  610.  
  611.     if (side != NULL) {
  612.     if (prevunit == NULL)
  613.       prevunit = side->unithead;
  614.     for (unit = prevunit->next; unit != prevunit; unit = unit->next) {
  615.         if (is_unit(unit)
  616.         && unit->id > 0
  617.         && alive(unit)
  618.         && inside_area(unit->x, unit->y)
  619.         && (unit->act && unit->act->acp > 0)
  620.         && (unit->plan && !unit->plan->asleep && !unit->plan->reserve && !unit->plan->delayed)) {
  621.         return unit;
  622.         }
  623.     } 
  624.     }
  625.     return NULL;
  626. }
  627.  
  628. Unit *
  629. find_prev_awake_mover(side, nextunit)
  630. Side *side;
  631. Unit *nextunit;
  632. {
  633.     Unit *unit = NULL;
  634.  
  635.     if (side != NULL) {
  636.     if (nextunit == NULL) nextunit = side->unithead;
  637.     for (unit = nextunit->prev; unit != nextunit; unit = unit->prev) {
  638.         if (is_unit(unit) && unit->id > 0
  639.         && alive(unit)
  640.         && inside_area(unit->x, unit->y)
  641.                 && (unit->act && unit->act->acp > 0)
  642.                 && (unit->plan && !unit->plan->asleep && !unit->plan->reserve && !unit->plan->delayed)) {
  643.         return unit;
  644.         }
  645.     } 
  646.     }
  647.     return NULL;
  648. }
  649.  
  650. /* Compute the total number of action points available to the side at the
  651.    beginning of the turn. */
  652.  
  653. int
  654. side_initacp(side)
  655. Side *side;
  656. {
  657.     int totacp = 0;
  658.     Unit *unit;
  659.  
  660.     for_all_side_units(side, unit) {
  661.     if (alive(unit) && unit->act) {
  662.         totacp += unit->act->initacp;
  663.     }
  664.     }
  665.     return totacp;
  666. }
  667.  
  668. /* Return the total of acp still unused by the side. */
  669.  
  670. int
  671. side_acp(side)
  672. Side *side;
  673. {
  674.     int acpleft = 0;
  675.     Unit *unit;
  676.  
  677.     for_all_side_units(side, unit) {
  678.     if (alive(unit) && unit->act) {
  679.         acpleft += unit->act->acp;
  680.     }
  681.     }
  682.     return acpleft;
  683. }
  684.  
  685. int
  686. side_acp_reserved(side)
  687. Side *side;
  688. {
  689.     int acpleft = 0;
  690.     Unit *unit;
  691.  
  692.     for_all_side_units(side, unit) {
  693.     if (alive(unit) && unit->act) {
  694.         if (unit->plan
  695.             && (unit->plan->reserve || unit->plan->asleep)) {
  696.             acpleft += unit->act->acp;
  697.         }
  698.     }
  699.     }
  700.     return acpleft;
  701. }
  702.  
  703. /* Return the total of acp still expected to be used by a human player. */
  704.  
  705. int
  706. side_acp_human(side)
  707. Side *side;
  708. {
  709.     int acpleft = 0;
  710.     Unit *unit;
  711.  
  712.     if (!side_has_display(side))
  713.       return acpleft;
  714.  
  715.     for_all_side_units(side, unit) {
  716.     if (unit != NULL
  717.         && alive(unit)
  718.         && inside_area(unit->x, unit->y)
  719.         && (unit->act
  720.         && unit->act->acp > 0)
  721.         && (unit->plan
  722.         && !unit->plan->asleep
  723.         && !unit->plan->reserve
  724.         && unit->plan->tasks == NULL)) {
  725.         acpleft += unit->act->acp;
  726.     }
  727.     }
  728.     return acpleft;
  729. }
  730.  
  731. /* (note that technology could be "factored out" of a game if all sides
  732.    reach max tech at some point) */
  733. /* (otherwise should compute once and cache) */
  734. /* (note that once tech factors out, can never factor in again) */
  735.  
  736. int
  737. using_tech_levels()
  738. {
  739.     int u;
  740.     Side *side;
  741.  
  742.     for_all_sides(side) {
  743.     for_all_unit_types(u) {
  744.         if (side->tech[u] < u_tech_max(u)) return TRUE;
  745.     }
  746.     }
  747.     return FALSE;
  748. }
  749.  
  750. /* Take the given side out of the game entirely.  This does not imply
  751.    winning or losing, nor does it take down the side's display or AI. */
  752.  
  753. void
  754. remove_side_from_game(side)
  755. Side *side;
  756. {
  757.     Side *side2;
  758.  
  759.     /* Officially flag this side as being no longer in the game. */
  760.     side->ingame = FALSE;
  761.     /* Update everybody on this. */
  762.     for_all_sides(side2) {
  763.     update_side_display(side2, side, TRUE);
  764.     }
  765.     /* Note that we no longer try to remove any images from other sides'
  766.        views, because even with the side gone, the images may be useful
  767.        information about where its units had gotten to.  For instance,
  768.        if a unit had been captured shortly before the side lost, then its
  769.        image might still correspond to an actual unit, with only its side
  770.        changed, and other sides may want to investigate for themselves. */
  771. }
  772.  
  773. int
  774. num_displayed_sides()
  775. {
  776.     int n = 0;
  777.     Side *side;
  778.  
  779.     for_all_sides(side) {
  780.     if (side_has_display(side)) ++n;
  781.     }
  782.     return n;
  783. }
  784.  
  785. void
  786. set_side_name(side, side2, newname)
  787. Side *side, *side2;
  788. char *newname;
  789. {
  790.     side2->name = newname;
  791.     /* (should inform all other sides!) */
  792.     update_side_display(side, side2, TRUE);
  793. }
  794.  
  795. #ifdef DESIGNERS
  796.  
  797. void
  798. become_designer(side)
  799. Side *side;
  800. {
  801.     Side *side2;
  802.  
  803.     if (!side->designer)
  804.       ++numdesigners;
  805.     side->designer = TRUE;
  806.     /* Designers have godlike power in the game, so mark it (permanently)
  807.        as no longer a normal game. */
  808.     compromised = TRUE;
  809.     update_everything();
  810.     for_all_sides(side2) {
  811.     update_side_display(side2, side, TRUE);
  812.     }
  813. }
  814.  
  815. void
  816. become_nondesigner(side)
  817. Side *side;
  818. {
  819.     Side *side2;
  820.  
  821.     if (side->designer)
  822.       --numdesigners;
  823.     side->designer = FALSE;
  824.     update_everything();
  825.     for_all_sides(side2) {
  826.     update_side_display(side2, side, TRUE);
  827.     }
  828. }
  829.  
  830. #endif /* DESIGNERS */
  831.  
  832. int
  833. trusted_side(side1, side2)
  834. Side *side1, *side2;
  835. {
  836.     if (side1 == side2)
  837.       return TRUE;
  838.     if (side1 == NULL || side2 == NULL || side1->trusts == NULL)
  839.       return FALSE;
  840.     return (side1->trusts[side_number(side2)]);
  841. }
  842.  
  843. void
  844. set_trust(side, side2, val)
  845. Side *side, *side2;
  846. int val;
  847. {
  848.     Side *side3;
  849.  
  850.     if (side == NULL || side2 == NULL || side == side2)
  851.       return;
  852.     if (side->trusts == NULL)
  853.       return;
  854.     side->trusts[side_number(side2)] = val;
  855.     /* This is a major change that all other sides will know about. */
  856.     for_all_sides(side3) {
  857.     update_side_display(side3, side, FALSE);
  858.     update_side_display(side3, side2, TRUE);
  859.     }
  860.     /* (should update views, list of units known about, etc) */
  861.     /* (if cell goes from exact to only recorded, update display anyhow) */
  862. }
  863.  
  864. void
  865. set_mutual_trust(side, side2, val)
  866. Side *side, *side2;
  867. int val;
  868. {
  869.     Side *side3;
  870.  
  871.     if (side == NULL || side2 == NULL || side == side2)
  872.       return;
  873.     if (side->trusts == NULL || side2->trusts == NULL)
  874.       return;
  875.     side->trusts[side_number(side2)] = val;
  876.     side2->trusts[side_number(side)] = val;
  877.     for_all_sides(side3) {
  878.     update_side_display(side3, side, FALSE);
  879.     update_side_display(side3, side2, TRUE);
  880.     }
  881.     /* (should update views, list of units known about, etc) */
  882. }
  883.  
  884. /* What interfaces should use to tweak the autofinish flag. */
  885.  
  886. void
  887. set_autofinish(side, value)
  888. Side *side;
  889. int value;
  890. {
  891.     side->autofinish = value;
  892. }
  893.  
  894. /* Being at war requires only ones of the sides to consider itself so. */
  895.  
  896. /* (Should the other side's relationships be tweaked also?) */
  897.  
  898. int
  899. enemy_side(s1, s2)
  900. Side *s1, *s2;
  901. {
  902.     if (trusted_side(s1, s2)) return FALSE;
  903.     return TRUE;
  904. }
  905.  
  906. /* A formal alliance requires the agreement of both sides. */
  907.  
  908. int
  909. allied_side(s1, s2)
  910. Side *s1, *s2;
  911. {
  912.     if (trusted_side(s1, s2)) return TRUE;
  913.     return FALSE;
  914. }
  915.  
  916. /* Neutralness is basically anything else. */
  917.  
  918. int
  919. neutral_side(s1, s2)
  920. Side *s1, *s2;
  921. {
  922.     return (!enemy_side(s1, s2) && !allied_side(s1, s2));
  923. }
  924.  
  925. void
  926. set_willing_to_save(side, flag)
  927. Side *side;
  928. int flag;
  929. {
  930.     int oldflag = side->willingtosave;
  931.     Side *side2;
  932.  
  933.     if (flag != oldflag) {
  934.     side->willingtosave = flag;
  935.     /* Inform everybody of our willingness to save. */ 
  936.     for_all_sides(side2) {
  937.         if (active_display(side2)) {
  938.         update_side_display(side2, side, TRUE);
  939.         }
  940.     }
  941.     }
  942. }
  943.  
  944. void
  945. set_willing_to_draw(side, flag)
  946. Side *side;
  947. int flag;
  948. {
  949.     int oldflag = side->willingtodraw;
  950.     Side *side2;
  951.  
  952.     if (flag != oldflag) {
  953.     side->willingtodraw = flag;
  954.     /* Inform everybody of our willingness to draw. */ 
  955.     for_all_sides(side2) {
  956.         if (active_display(side2)) {
  957.         update_side_display(side2, side, TRUE);
  958.         }
  959.     }
  960.     }
  961. }
  962.  
  963. /* Set the self-unit of the given side.  This is only called when done at
  964.    the direction of the side, and may fail if the side can't change its
  965.    self-unit voluntarily.  Return success or failure of change. */
  966.  
  967. int
  968. set_side_selfunit(side, unit)
  969. Side *side;
  970. Unit *unit;
  971. {
  972.     if (!in_play(unit))
  973.       return FALSE;
  974.     if (side->selfunit
  975.         && in_play(side->selfunit)
  976.         && !u_self_changeable(side->selfunit->type))
  977.       return FALSE;
  978.     side->selfunit = unit;
  979.     /* (should update some part of display?) */
  980.     return TRUE;
  981. }
  982.  
  983. /* Message-forwarding function. */
  984.  
  985. void
  986. send_message(side, sidemask, str)
  987. Side *side;
  988. long sidemask;
  989. char *str;
  990. {
  991.     Side *side2;
  992.  
  993.     for_all_sides(side2) {
  994.     if (side2 != side && (sidemask & (1 << side2->id))) {
  995.         receive_message(side2, side, str);
  996.     }
  997.     }
  998. }
  999.  
  1000. /* Handle the receipt of a message.  Some messages may result in specific
  1001.    actions, but the default is just to forward to AIs and displays. */
  1002.  
  1003. void
  1004. receive_message(side, sender, str)
  1005. Side *side, *sender;
  1006. char *str;
  1007. {
  1008.     /* First look for specially-recognized messages. */
  1009.     if (strcmp("%reveal", str) == 0) {
  1010.     reveal_side(sender, side, NULL);
  1011.     } else {
  1012.     /* Give the message to interface if present. */
  1013.     if (side_has_display(side)) {
  1014.         update_message_display(side, sender, str, TRUE);
  1015.     }
  1016.     /* Also give the message to any AI. */
  1017.     if (side_has_ai(side)) {
  1018.         ai_receive_message(side, sender, str);
  1019.     }
  1020.     }
  1021. }
  1022.  
  1023. /* General method for passing along info about one side to another. */
  1024.  
  1025. void
  1026. reveal_side(sender, recipient, types)
  1027. Side *sender, *recipient;
  1028. int *types;
  1029. {
  1030.     int x, y;
  1031.     Unit *unit;
  1032.  
  1033.     if (g_see_all()) return;
  1034.     if (!g_terrain_seen()) {
  1035.     for_all_cells(x, y) {
  1036.         if (terrain_view(sender, x, y) != UNSEEN
  1037.             && terrain_view(recipient, x, y) == UNSEEN) {
  1038.             set_terrain_view(recipient, x, y, terrain_view(sender, x, y));
  1039.             /* (should update unit views also) */
  1040.         update_cell_display(recipient, x, y, TRUE);
  1041.         }
  1042.     }
  1043.     }
  1044.     for_all_side_units(sender, unit) {
  1045.     if (in_play(unit) && (types == NULL || types[unit->type])) {
  1046.         see_exact(recipient, unit->x, unit->y);
  1047.         update_cell_display(recipient, unit->x, unit->y, TRUE);
  1048.     }
  1049.     }
  1050. }
  1051.  
  1052. /* Vision. */
  1053.  
  1054. /* What happens when a unit appears on a given cell. */
  1055.  
  1056. /* An always-seen unit has builtin spies/tracers to inform everybody else of
  1057.    all its movements.  When such a unit occupies a cell, coverage is turned
  1058.    on and remains on until the unit leaves that cell. */
  1059.  
  1060. /* If this unit with onboard spies wanders into unknown territory,
  1061.    shouldn't that territory become known as well?  I think the unseen
  1062.    test should only apply during initialization. */
  1063. /* But if always-seen unit concealed during init, will magically appear
  1064.    when it first moves! */
  1065.  
  1066. void
  1067. all_see_occupy(unit, x, y, inopen)
  1068. Unit *unit;
  1069. int x, y;
  1070. int inopen;
  1071. {
  1072.     Side *side;
  1073.     int seeall = g_see_all(), always = u_see_always(unit->type);
  1074.  
  1075.     for_all_sides(side) {
  1076.     if (seeall) {
  1077.         update_cell_display(side, x, y, TRUE);
  1078.     } if (side_sees_unit(side, unit)) {
  1079.         see_cell(side, x, y);
  1080.     } else {
  1081.         if (always && terrain_view(side, x, y) != UNSEEN) {
  1082.         if (side->coverage) add_cover(side, x, y, 1);
  1083.         }
  1084.         if (inopen || always) {
  1085.         see_cell(side, x, y);
  1086.         }
  1087.     }
  1088.     }
  1089.     {
  1090.     int dir, x1, y1;
  1091.     Unit *unit2, *unit3;
  1092.             
  1093.     for_all_directions(dir) {
  1094.        if (interior_point_in_dir(x, y, dir, &x1, &y1)) {
  1095.            for_all_stack(x1, y1, unit2) {
  1096.                if (unit2->side != NULL
  1097.                    && unit2->side != unit->side
  1098.                    && (seeall || (unit2->side->coverage && cover(unit2->side, x1, y1) > 0))
  1099.                    && !unit_trusts_unit(unit2, unit)) {
  1100.                    wake_unit(unit2, FALSE, 0, NULL);
  1101.                }
  1102.                for_all_occupants(unit2, unit3) {
  1103.                    if (unit3->side != NULL
  1104.                        && unit3->side != unit->side
  1105.                        && (seeall || (unit3->side->coverage && cover(unit3->side, x1, y1) > 0))
  1106.                        && !unit_trusts_unit(unit3, unit)) {
  1107.                        wake_unit(unit3, FALSE, 0, NULL);
  1108.                    }
  1109.                }
  1110.            }
  1111.        }
  1112.     }        
  1113.     }
  1114. }
  1115.  
  1116. /* Some highly visible unit types cannot leave a cell without everybody
  1117.    knowing about the event.  The visibility is attached to the unit, not
  1118.    the cell, so first the newly-empty cell is viewed, then view coverage
  1119.    is decremented. */
  1120.  
  1121. void
  1122. all_see_leave(unit, x, y, inopen)
  1123. Unit *unit;
  1124. int x, y;
  1125. int inopen;
  1126. {
  1127.     Side *side;
  1128.     int seeall = g_see_all(), always = u_see_always(unit->type);
  1129.     int olduview;
  1130.  
  1131.     for_all_sides(side) {
  1132.     if (seeall) {
  1133.         update_cell_display(side, x, y, TRUE);
  1134.     } else if (side_sees_unit(side, unit)) {
  1135.         see_cell(side, x, y);
  1136.     } else {
  1137.         if (always && terrain_view(side, x, y) != UNSEEN) {
  1138.         see_cell(side, x, y);
  1139.         if (side->coverage && cover(side, x, y) > 0) add_cover(side, x, y, -1);
  1140.         }
  1141.         /* Won't be called twice, because view coverage is 0 now. */
  1142.         if (inopen) {
  1143.         see_cell(side, x, y);
  1144.         }
  1145.         /* special hack to flush images we *know* are garbage */
  1146.         if (side->coverage && cover(side, x, y) < 1) {
  1147.             olduview = unit_view(side, x, y);
  1148.             
  1149.             if (vside(olduview) == side_number(side)) {
  1150.                 set_unit_view(side, x, y, EMPTY);
  1151.                 set_unit_view_date(side, x, y, g_turn());
  1152.             update_cell_display(side, x, y, FALSE);
  1153.             }
  1154.         }
  1155.     }
  1156.     }
  1157. }
  1158.  
  1159. static int tmpx0, tmpy0, tmpz0;
  1160.  
  1161. static void
  1162. init_visible_elevation(x, y)
  1163. int x, y;
  1164. {
  1165.     int elev = (elevations_defined() ? elev_at(x, y) : 0);
  1166.  
  1167.     set_tmp1_at(x, y, elev - tmpz0);
  1168. }
  1169.  
  1170. static void
  1171. calc_visible_elevation(x, y)
  1172. int x, y;
  1173. {
  1174.     int dir, x1, y1, elev, tmp, tmpa, tmpb, adjelev = 9999, viselev, dist, dist1;
  1175.     int cellwid = area.cellwidth;
  1176.  
  1177.     elev = (elevations_defined() ? elev_at(x, y) : 0);
  1178.     dist = distance(x, y, tmpx0, tmpy0);
  1179.     if (cellwid <= 0) cellwid = 1;
  1180.     for_all_directions(dir) {
  1181.     if (point_in_dir(x, y, dir, &x1, &y1)) {
  1182.       dist1 = distance(x1, y1, tmpx0, tmpy0);
  1183.       if (dist1 < dist) {
  1184.         tmpa = tmp1_at(x1, y1);
  1185.         /* Account for the screening effect of the elevation difference. */
  1186.         /* (dist1 will never be zero) */
  1187.         tmpa = (tmpa * dist * cellwid) / (dist1 * cellwid);
  1188.         tmpb = (elevations_defined() ? elev_at(x1, y1) : 0)
  1189.                + t_thickness(terrain_at(x1, y1))
  1190.                - tmpz0;
  1191.         tmpb = (tmpb * dist * cellwid) / (dist1 * cellwid);
  1192.         tmp = max(tmpa, tmpb);
  1193.         adjelev = min(adjelev, tmp);
  1194.       }
  1195.     }
  1196.     }
  1197.     viselev = max(adjelev, elev);
  1198.     set_tmp1_at(x, y, viselev - tmpz0);
  1199. }
  1200.  
  1201. /* Unit's beady eyes are now covering (or not, depending on sign of onoff)
  1202.    the immediate area.
  1203.    Since new things may be coming into view, we have to check and maybe
  1204.    draw lots of cells (but only need the one output flush, fortunately). */
  1205.  
  1206. /* (LOS comes in here, to make irregular coverage areas) */
  1207.  
  1208. void
  1209. cover_area(side, unit, x0, y0, onoff)
  1210. Side *side;
  1211. Unit *unit;
  1212. int x0, y0, onoff;
  1213. {
  1214.     int u = unit->type, range, x, y, x1, y1, x2, y2, y1c, y2c, xw, cov, los, r;
  1215.     extern int daynight, sunx, suny;
  1216.     
  1217.     if (side == NULL
  1218.     || side->coverage == NULL
  1219.         || indep(unit)
  1220.     || g_see_all()
  1221.     || !in_area(unit->x, unit->y)
  1222.     || !completed(unit)
  1223.     )
  1224.       return;
  1225.     range = u_vision_range(u);
  1226.     /* Adjust for the effects of nighttime on vision range. */
  1227.     if (night_at(x0, y0)) {
  1228.         range = (range * ut_vision_night_effect(u, terrain_at(x0, y0))) / 100;
  1229.     }
  1230.     los = FALSE;
  1231.     /* (should also adjust for effect of clouds here) */
  1232.     if (u_vision_bend(u) != 100) {
  1233.     los = TRUE;
  1234.     /* Need one scratch layer, will be used for visible elevation cache. */
  1235.     allocate_area_scratch(1);
  1236.     /* Compute the minimum elevation for visibility at each cell. */
  1237.     apply_to_area(x0, y0, range, init_visible_elevation);
  1238.     /* Leave own and adj cells alone, will always be visible. */
  1239.     tmpx0 = x0;  tmpy0 = y0;
  1240.     tmpz0 = (elevations_defined() ? elev_at(x0, y0) : 0)
  1241.       + unit_alt(unit)
  1242.         * ut_eye_height(unit->type, terrain_at(x0, y0));
  1243.     for (r = 2; r <= range; ++r) {
  1244.         apply_to_ring(x0, y0, r, r, calc_visible_elevation);
  1245.     }
  1246.     /* We now have a layer indicating how high things must be to be visible. */
  1247.     }
  1248.     /* These may be outside the area - necessary since units may be able
  1249.        to see farther in x than the height of the area. */
  1250.     y1 = y1c = y0 - range;
  1251.     y2 = y2c = y0 + range;
  1252.     /* Clip the iteration bounds though. */
  1253.     if (y1c < 0) y1c = 0;
  1254.     if (y2c > area.height - 1) y2c = area.height - 1;
  1255.     for (y = y1c; y <= y2c; ++y) {
  1256.     x1 = x0 - (y < y0 ? (y - y1) : range);
  1257.     x2 = x0 + (y > y0 ? (y2 - y) : range);
  1258.     for (x = x1; x <= x2; ++x) {
  1259.         if (in_area(x, y)) {
  1260.         if (!los
  1261.             || (tmp1_at(x, y)
  1262.             <= ((elevations_defined()
  1263.                  ? elev_at(x, y) : 0)
  1264.                 + t_thickness(terrain_at(x, y))))) {
  1265.             xw = wrapx(x);
  1266.             cov = onoff + cover(side, xw, y);
  1267.             if (cov < 0) {
  1268.             Dprintf("Negative coverage for %s at %d,%d\n",
  1269.                 side_desig(side), xw, y);
  1270.             }
  1271.             set_cover(side, xw, y, cov);
  1272.             /* View the cell and maybe get excited. */
  1273.             if (onoff > 0 && see_cell(side, xw, y))
  1274.               react_to_seen_unit(side, unit, xw, y);
  1275.         }
  1276.         }
  1277.     }
  1278.     }
  1279.     /* If we're seeing new things, make sure they're on the display. */
  1280.     if (onoff > 0)
  1281.       flush_display_buffers(side);
  1282. }
  1283.  
  1284. /* Use this to clear out garbled view coverage. */
  1285.  
  1286. void
  1287. reset_coverage()
  1288. {
  1289.     Side *side;
  1290.  
  1291.     if (g_see_all())
  1292.       return;
  1293.     for_all_sides(side)
  1294.       calc_coverage(side);
  1295. }
  1296.  
  1297. /* Calculate/recalculate the view coverage layers of a side. */
  1298.  
  1299. void
  1300. calc_coverage(side)
  1301. Side *side;
  1302. {
  1303.     int x, y, s2, pop, visible[MAXSIDES];
  1304.     Unit *unit;
  1305.  
  1306.     if (side->coverage == NULL)
  1307.       return;
  1308.     Dprintf("Calculating all view coverage for %s\n", side_desig(side));
  1309.     /* Either init all cells to 0, or use populations to decide. */
  1310.     if (people_sides_defined()) {
  1311.     for (s2 = 0; s2 <= numsides; ++s2)
  1312.       visible[s2] = (trusted_side(side_n(s2), side) ? 1 : 0);
  1313.     /* (should add controlled sides too) */
  1314.     for_all_cells(x, y) {
  1315.         pop = people_side_at(x, y);
  1316.         set_cover(side, x, y, ((pop != NOBODY && visible[pop]) ? 1 : 0));
  1317.     }
  1318.     } else {
  1319.     for_all_cells(x, y) {
  1320.         set_cover(side, x, y, 0);
  1321.     }
  1322.     }
  1323.     /* Add coverage by the units already in place. */
  1324.     for_all_units(unit) {
  1325.     if (in_play(unit) && trusted_side(unit->side, side)) {
  1326.         cover_area(side, unit, unit->x, unit->y, 1);
  1327.     }
  1328.     }
  1329. }
  1330.  
  1331. void
  1332. reset_all_views()
  1333. {
  1334.     Side *side;
  1335.  
  1336.     if (g_see_all()) return;
  1337.     for_all_sides(side) {
  1338.     reset_view(side);
  1339.     }
  1340. }
  1341.  
  1342. void
  1343. reset_view(side)
  1344. Side *side;
  1345. {
  1346.     int x, y, uview;
  1347.  
  1348.     for_all_cells(x, y) {
  1349.     if (cover(side, x, y) == 0
  1350.         && ((uview = unit_view(side, x, y)) != EMPTY)
  1351.         && vside(uview) == side_number(side)) {
  1352.         set_unit_view(side, x, y, EMPTY);
  1353.     }
  1354.     }
  1355. }
  1356.  
  1357. void
  1358. react_to_seen_unit(side, unit, x, y)
  1359. Side *side;
  1360. Unit *unit;
  1361. int x, y;
  1362. {
  1363.     int uview, eu;
  1364.     Unit *eunit;
  1365.     Side *es;
  1366.  
  1367.     if (g_see_all() /* see real unit */) {
  1368.         /* (should look at all of stack if can be mixed) */
  1369.     if ((eunit = unit_at(x, y)) != NULL) {
  1370.         if (react_to_enemies(unit) && !allied_side(eunit->side, side)) {
  1371.         /* should do a more general alarm */
  1372.             wake_unit(unit, TRUE, 0, NULL);
  1373.         }
  1374.     }
  1375.     } else if (side->coverage != NULL) {
  1376.     uview = unit_view(side, x, y);
  1377.         if (uview != EMPTY) {
  1378.             eu = vtype(uview);  es = side_n(vside(uview));
  1379.             /* react only to certain utypes? */
  1380.         if (react_to_enemies(unit) && !allied_side(es, side)) {
  1381.         /* should do a more general alarm */
  1382.         wake_unit(unit, TRUE, 0, NULL);
  1383.         }
  1384.         }
  1385.     } else {
  1386.         /* ??? */
  1387.     }
  1388. }
  1389.  
  1390. extern void compute_see_chances PROTO ((void));
  1391.  
  1392. int any_see_chances = -1;
  1393.  
  1394. int any_people_see_chances = -1;
  1395.  
  1396. int max_see_chance_range;
  1397.  
  1398. /* Determine whether there is any possibility of an uncertain sighting,
  1399.    and cache the conclusion. */
  1400.  
  1401. void
  1402. compute_see_chances()
  1403. {
  1404.     int u1, u2, m1;
  1405.  
  1406.     any_see_chances = FALSE;
  1407.     any_people_see_chances = FALSE;
  1408.     max_see_chance_range = -1;
  1409.     for_all_unit_types(u2) {
  1410.     for_all_unit_types(u1) {
  1411.         if (uu_see_at(u1, u2) != 100) {
  1412.         any_see_chances = TRUE;
  1413.         max_see_chance_range = max(max_see_chance_range, 0);
  1414.         }
  1415.         if (uu_see_adj(u1, u2) != 100) {
  1416.         any_see_chances = TRUE;
  1417.         max_see_chance_range = max(max_see_chance_range, 1);
  1418.         }
  1419.         if (uu_see(u1, u2) != 100) {
  1420.         any_see_chances = TRUE;
  1421.         max_see_chance_range = max(max_see_chance_range, u_vision_range(u1));
  1422.         }
  1423.     }
  1424.     for_all_material_types(m1) {
  1425.         if (um_people_see(u2, m1)) {
  1426.         any_people_see_chances = TRUE;
  1427.         }
  1428.     }
  1429.     }
  1430. }
  1431.  
  1432. int test_for_viewer PROTO ((int x, int y));
  1433.  
  1434. static Unit *tmpunittosee, *tmpunitseen;
  1435.  
  1436. int
  1437. test_for_viewer(x, y)
  1438. int x, y;
  1439. {
  1440.     int u2 = tmpunittosee->type, x2 = tmpunittosee->x, y2 = tmpunittosee->y, dist, chance;
  1441.     Unit *unit;
  1442.  
  1443.     dist = distance(x, y, x2, y2);
  1444.     for_all_stack(x, y, unit) {
  1445.     if (dist == 1)
  1446.       chance = uu_see_adj(unit->type, u2);
  1447.     else
  1448.       /* (should interpolate according to distance?) */
  1449.       chance = uu_see(unit->type, u2);
  1450.     chance = (chance * ut_visibility(u2, terrain_at(x2, y2))) / 100;
  1451.     if (chance >= 100 || probability(chance)) {
  1452.         tmpunitseen = tmpunittosee;
  1453.         return TRUE;
  1454.     }
  1455.     }
  1456.     return FALSE;
  1457. }
  1458.  
  1459. /* Update the view of this cell for everybody's benefit.  May have to write
  1460.    to many displays. */
  1461.  
  1462. void
  1463. all_see_cell(x, y)
  1464. int x, y;
  1465. {
  1466.     register Side *side;
  1467.  
  1468.     for_all_sides(side) {
  1469.     see_cell(side, x, y);
  1470.     }
  1471. }
  1472.  
  1473. /* Look at the given position, possibly not seeing anything.  Return true if
  1474.    a unit was spotted. */
  1475.  
  1476. int
  1477. see_cell(side, x, y)
  1478. Side *side;
  1479. int x, y;
  1480. {
  1481.     int update, chance, t, curtview, curuview, newuview, x1, y1, m;
  1482.     Unit *unit, *unitseen;
  1483.     
  1484.     if (side == NULL || side == indepside || !in_area(x, y))
  1485.       return FALSE;
  1486.     update = FALSE;
  1487.     unitseen = NULL;
  1488.     /* If we see everything, just pass through to updating the display. */
  1489.     if (g_see_all()) {
  1490.         update = TRUE;
  1491.         unitseen = unit_at(x, y);
  1492.     } else if (side->coverage != NULL && cover(side, x, y) > 0) {
  1493.         /* Always update our knowledge of the terrain. */
  1494.         curtview = terrain_view(side, x, y);
  1495.      if (curtview == UNSEEN) {
  1496.         set_terrain_view(side, x, y, buildtview(terrain_at(x, y)));
  1497.         update = TRUE;
  1498.     }
  1499.     if (any_see_chances < 0)
  1500.       compute_see_chances();
  1501.        curuview = unit_view(side, x, y);
  1502.        for_all_stack(x, y, unit) {
  1503.         if (side_sees_unit(side, unit)) {
  1504.         unitseen = unit;
  1505.         break;
  1506.         } else if (any_see_chances) {
  1507.             /* (should always check for viewers at x,y first) */
  1508.         if (max_see_chance_range > 0) {
  1509.             tmpunittosee = unit;
  1510.             if (search_around(x, y, max_see_chance_range, test_for_viewer,
  1511.                           &x1, &y1, 1)) {
  1512.                 unitseen = tmpunitseen;
  1513.                 break;
  1514.             }
  1515.         }
  1516.         } else {
  1517.         t = terrain_at(x, y);
  1518.         chance = ut_visibility(unit->type, t);
  1519.         if (chance >= 100 || probability(chance)) {
  1520.             unitseen = unit;
  1521.             break;
  1522.         }
  1523.         }
  1524.     }
  1525.     /* See if any people in the cell see something. */
  1526.     if (any_people_see_chances
  1527.         && unitseen == NULL
  1528.         && any_cell_materials_defined()) {
  1529.            for_all_stack(x, y, unit) {
  1530.         for_all_material_types(m) {
  1531.             if (cell_material_defined(m)
  1532.             && material_at(x, y, m) > 0) {
  1533.             chance = um_people_see(unit->type, m);
  1534.             if (probability(chance)) {
  1535.                 unitseen = unit;
  1536.                 break;
  1537.             }
  1538.             }
  1539.         }
  1540.         if (unitseen != NULL)
  1541.           break;
  1542.            }
  1543.     }
  1544.     if (unitseen) {
  1545.         newuview = builduview(side_number(unitseen->side), unitseen->type);
  1546.         if (curuview != newuview) {
  1547.         /* We're seeing something different from what used to be there. */
  1548.         set_unit_view(side, x, y, newuview);
  1549.             set_unit_view_date(side, x, y, g_turn());
  1550.         update = TRUE;
  1551.         } else {
  1552.             /* Same as we already know, so not considered a change. */
  1553.             unitseen = NULL;
  1554.         }
  1555.     } else if (curuview != EMPTY) {
  1556.         set_unit_view(side, x, y, EMPTY);
  1557.         set_unit_view_date(side, x, y, g_turn());
  1558.         update = TRUE;
  1559.     }
  1560.     }
  1561.     /* If there was any change in what was visible, tell the display. */
  1562.     if (update) {
  1563.     update_cell_display(side, x, y, FALSE);
  1564.     }
  1565.     return (unitseen != NULL);
  1566. }
  1567.  
  1568. /* "Bare-bones" viewing, for whenever you know exactly what's there.
  1569.    This is the lowest level of all viewing routines, and executed a lot. */
  1570.  
  1571. void
  1572. see_exact(side, x, y)
  1573. Side *side;
  1574. int x, y;
  1575. {
  1576.     register int olduview, oldtview, newtview, newuview, update;
  1577.     register Unit *unit;
  1578.  
  1579.     if (side == NULL || side == indepside || !in_area(x, y))
  1580.       return;
  1581.     if (g_see_all()) {
  1582.     /* It may not really be necessary to do anything to the display, but
  1583.        the kernel doesn't know if the interface is drawing all the units
  1584.        that are visible, or is only drawing "interesting" ones, or whatever.
  1585.        It would be up to the interface to decide that, say, its magnification
  1586.        power for a map is such that only one unit is being displayed, and
  1587.        that the update from here doesn't result in any visible changes to
  1588.        what's already been drawn on the screen. */
  1589.         update = TRUE;
  1590.     } else {
  1591.         oldtview = terrain_view(side, x, y);
  1592.         newtview = buildtview(terrain_at(x, y));
  1593.         set_terrain_view(side, x, y, newtview);
  1594.         olduview = unit_view(side, x, y);
  1595.         newuview = EMPTY;
  1596.         unit = unit_at(x, y);
  1597.     if (unit != NULL)
  1598.       newuview = builduview(side_number(unit->side), unit->type);
  1599.     set_unit_view(side, x, y, newuview);
  1600.     set_unit_view_date(side, x, y, g_turn());
  1601.     update = (oldtview != newtview || olduview != newuview);
  1602.     }
  1603.     /* If there was any change in what was visible, tell the display. */
  1604.     if (update) {
  1605.     update_cell_display(side, x, y, FALSE);
  1606.     }
  1607. }
  1608.  
  1609. /* A border has been seen if the cell on either side has been seen. */
  1610.  
  1611. int
  1612. seen_border(side, x, y, dir)
  1613. Side *side;
  1614. int x, y, dir;
  1615. {
  1616.     int x1, y1;
  1617.  
  1618.     if (g_see_all())
  1619.       return TRUE;
  1620.     if (terrain_view(side, x, y) != UNSEEN)
  1621.       return TRUE;
  1622.     if (point_in_dir(x, y, dir, &x1, &y1))
  1623.       if (terrain_view(side, x1, y1) != UNSEEN)
  1624.     return TRUE;
  1625.     return FALSE;
  1626. }
  1627.  
  1628. /* Make a printable identification of the given side. */
  1629.  
  1630. char *
  1631. side_desig(side)
  1632. Side *side;
  1633. {
  1634.     if (sidedesigbuf == NULL)
  1635.       sidedesigbuf = xmalloc(BUFSIZE);
  1636.     if (side != NULL) {
  1637.     sprintf(sidedesigbuf, "s%d (%s)", side_number(side), side_name(side));
  1638.     if (side->selfunit) {
  1639.         tprintf(sidedesigbuf, "(self is #%d)", side->selfunit->id);
  1640.     }
  1641.     } else {
  1642.     sprintf(sidedesigbuf, "nullside");
  1643.     }
  1644.     return sidedesigbuf;
  1645. }
  1646.  
  1647. /* Add a player into the list of players.  All values are defaults here. */
  1648.  
  1649. Player *
  1650. add_player()
  1651. {
  1652.     Player *player = (Player *) xmalloc(sizeof(Player));
  1653.  
  1654.     player->id = nextplayerid++;
  1655.     /* Note that all names and suchlike slots are NULL. */
  1656.     ++numplayers;
  1657.     /* Add this one to the end of the player list. */
  1658.     if (last_player == NULL) {
  1659.     playerlist = last_player = player;
  1660.     } else {
  1661.     last_player->next = player;
  1662.     last_player = player;
  1663.     }
  1664.     Dprintf("Added a player\n");
  1665.     return player;
  1666. }
  1667.  
  1668. Player *
  1669. find_player(n)
  1670. int n;
  1671. {
  1672.     Player *player;
  1673.  
  1674.     for (player = playerlist; player != NULL; player = player->next)
  1675.       if (player->id == n)
  1676.     return player;
  1677.     return NULL;
  1678. }
  1679.  
  1680. /* Transform a player object into a regularized form. */
  1681.  
  1682. void
  1683. canonicalize_player(player)
  1684. Player *player;
  1685. {
  1686.     if (player == NULL)
  1687.       return;
  1688.     if (empty_string(player->displayname))
  1689.       player->displayname = NULL;
  1690.     if (empty_string(player->aitypename))
  1691.       player->aitypename = NULL;
  1692. }
  1693.  
  1694. /* Make a printable identification of the given player. */
  1695.  
  1696. char *
  1697. player_desig(player)
  1698. Player *player;
  1699. {
  1700.     if (playerdesigbuf == NULL)
  1701.       playerdesigbuf = xmalloc(BUFSIZE);
  1702.     if (player != NULL) {
  1703.     sprintf(playerdesigbuf, "%s,%s/%s@%s+%d",
  1704.         (player->name ? player->name : ""),
  1705.         (player->aitypename ? player->aitypename : ""),
  1706.         (player->configname ? player->configname : ""),
  1707.         (player->displayname ? player->displayname : ""),
  1708.         player->advantage);
  1709.     } else {
  1710.     sprintf(playerdesigbuf, "nullplayer");
  1711.     }
  1712.     return playerdesigbuf;
  1713. }
  1714.  
  1715. /* Agreement handling here for now. */
  1716.  
  1717. Agreement *agreementlist = NULL;
  1718.  
  1719. Agreement *lastagreement;
  1720.  
  1721. int numagreements = 0;
  1722.  
  1723. void
  1724. init_agreements()
  1725. {
  1726.     agreementlist = lastagreement = NULL;
  1727.     numagreements = 0;
  1728. }
  1729.  
  1730. Agreement *
  1731. create_agreement(id)
  1732. int id;
  1733. {
  1734.     Agreement *ag = (Agreement *) xmalloc(sizeof(Agreement));
  1735.  
  1736.     ag->id = id;
  1737.     ag->terms = lispnil;
  1738.     ag->next = NULL;
  1739.     if (agreementlist != NULL) {
  1740.     lastagreement->next = ag;
  1741.     } else {
  1742.     agreementlist = lastagreement = ag;
  1743.     }
  1744.     ++numagreements;
  1745.     return ag;
  1746. }
  1747.  
  1748. char agreementdesigbuf[BUFSIZE];
  1749.  
  1750. char *
  1751. agreement_desig(ag)
  1752. Agreement *ag;
  1753. {
  1754.     sprintf(agreementdesigbuf, "<ag %s %s %s>",
  1755.         (ag->typename ? ag->typename : "(null)"),
  1756.         (ag->name ? ag->name : "(null)"),
  1757.         (ag->terms == lispnil ? "(no terms)" : "...terms..."));
  1758.     return agreementdesigbuf;
  1759. }
  1760.  
  1761. #if 0
  1762.     } else if (strcmp(msg, "briefing") == 0) {
  1763.         notify("Receiving a briefing from the %s...",
  1764.            plural_form(side->name));
  1765.         reveal_side(side, reqside, 100);
  1766.         notify("You just briefed the %s on your position.",
  1767.            plural_form(reqside->name));
  1768.     } else if (strcmp(msg, "alliance") == 0) {
  1769.         notify("You propose a formal alliance with the %s.",
  1770.            plural_form(reqside->name));
  1771.         side->relationships[side_number(reqside)] = ALLY;
  1772.         if (reqside->relationships[side_number(side)] >= ALLY) {
  1773.         declare_alliance(side, reqside);
  1774.         for_all_sides(side3) redraw(side3);
  1775.         } else {
  1776.         notify("The %s propose a formal alliance.",
  1777.                plural_form(side->name));
  1778.         }
  1779.     } else if (strcmp(msg, "neutral") == 0) {
  1780.         notify("You propose neutrality with the %s.",
  1781.            plural_form(reqside->name));
  1782.         side->relationships[side_number(reqside)] = NEUTRAL;
  1783.         if (reqside->relationships[side_number(side)] == NEUTRAL) {
  1784.         declare_neutrality(side, reqside);
  1785.         for_all_sides(side3) redraw(side3);
  1786.         } else {
  1787.         notify("The %s propose neutrality.",
  1788.                plural_form(side->name));
  1789.         }
  1790.     } else if (strcmp(msg, "war") == 0) {
  1791.         notify("You declare war on the %s!",
  1792.            plural_form(reqside->name));
  1793.         declare_war(side, reqside);
  1794.         for_all_sides(side3) redraw(side3);
  1795. #endif
  1796.  
  1797. #ifdef DESIGNERS
  1798.  
  1799. static int tmpint;
  1800. static int tmpint2;
  1801.  
  1802. static void
  1803. paint_view_1(x, y)
  1804. int x, y;
  1805. {
  1806.     int oldtview = terrain_view(tmpside, x, y);
  1807.     int olduview = unit_view(tmpside, x, y);
  1808.  
  1809.     if (oldtview != tmpint || olduview != tmpint2) {
  1810.     set_terrain_view(tmpside, x, y, tmpint);
  1811.     set_unit_view(tmpside, x, y, tmpint2);
  1812.     see_exact(tmpside, x, y);
  1813.     }
  1814. }
  1815.  
  1816. void
  1817. paint_view(side, x, y, r, tview, uview)
  1818. Side *side;
  1819. int x, y, r, tview, uview;
  1820. {
  1821.     tmpside = side;
  1822.     tmpint = tview;
  1823.     tmpint2 = uview;
  1824.     apply_to_area_plus_edge(x, y, r, paint_view_1);
  1825. }
  1826.  
  1827. #endif /* DESIGNERS */
  1828.